From c39cf96834d26b3b7c79f127a3cfa1b9023224bc Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Wed, 9 Mar 2022 09:34:26 -0700 Subject: [PATCH] misc improvements. (#861) * misc improvements. fix memory leak in nmea reader. eliminate extra string conversion using xml_parse_time. use local QByteArray instead of xstrdup. convert human_to_dec interface to QString. * use strtod to track converted len in human_to_dec. * enhance humantodec test. --- csv_util.cc | 33 ++++--------- csv_util.h | 6 +-- gpx.cc | 5 +- nmea.cc | 3 ++ reference/humantodec.gpx | 100 ++++++++++++++++++++++++++++++++++++++ reference/humantodec1.csv | 20 ++++++++ reference/humantodec2.csv | 20 ++++++++ testo.d/unicsv.test | 5 ++ xcsv.cc | 8 +-- 9 files changed, 165 insertions(+), 35 deletions(-) create mode 100644 reference/humantodec.gpx create mode 100644 reference/humantodec1.csv create mode 100644 reference/humantodec2.csv diff --git a/csv_util.cc b/csv_util.cc index f522bee69..65448e24f 100644 --- a/csv_util.cc +++ b/csv_util.cc @@ -21,12 +21,11 @@ */ #include // for assert -#include // for isspace #include // for fabs -#include // for size_t #include // for atof, strtod #include // for strlen, strchr, strncmp, strcmp, memmove, strcpy, strcspn, strncpy +#include // for QByteArray #include // for QChar #include // for QDebug #include // for QRegularExpression @@ -331,14 +330,14 @@ ddmmdir_to_degrees(const char* ddmmdir) /***************************************************************************** * human_to_dec() - convert a "human-readable" lat and/or lon to decimal - * usage: human_to_dec( "N 41� 09.12' W 085� 09.36'", &lat, &lon ); + * usage: human_to_dec( "N 41° 09.12′ W 085° 09.36′", &lat, &lon ); * human_to_dec( "41 9 5.652 N", &lat, &lon ); * * which: 0-no preference 1-prefer lat 2-prefer lon *****************************************************************************/ void -human_to_dec(const char* instr, double* outlat, double* outlon, int which) +human_to_dec(const QString& instr, double* outlat, double* outlon, int which) { double unk[3] = {999,999,999}; double lat[3] = {999,999,999}; @@ -347,21 +346,12 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which) int lonsign = 0; int unksign = 1; - const char* cur; double* numres = unk; int numind = 0; - char* buff = nullptr; - if (strchr(instr, ',') != nullptr) { - char* c; - buff = xstrdup(instr); - while ((c = strchr(buff, ','))) { - *c = '.'; - } - cur = buff; - } else { - cur = instr; - } + // Allow comma as decimal separator. + const QByteArray inbytes = instr.toUtf8().replace(',', '.'); + const char* cur = inbytes.constData(); while (cur && *cur) { switch (*cur) { @@ -424,11 +414,9 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which) case '9': case '0': case '.': - case ',': - numres[numind] = atof(cur); - while (cur && *cur && strchr("1234567890.,",*cur)) { - cur++; - } + char* end; + numres[numind] = strtod(cur, &end); + cur = end; break; case '-': unksign = -1; @@ -495,9 +483,6 @@ human_to_dec(const char* instr, double* outlat, double* outlon, int which) *outlon *= lonsign; } } - if (buff) { - xfree(buff); - } } /* diff --git a/csv_util.h b/csv_util.h index c0461bb24..57789407e 100644 --- a/csv_util.h +++ b/csv_util.h @@ -58,11 +58,7 @@ double ddmmdir_to_degrees(const char* ddmmdir); void -human_to_dec(const char* instr, double* outlat, double* outlon, int which); -inline void -human_to_dec(const QString& instr, double* outlat, double* outlon, int which) { - human_to_dec(CSTR(instr), outlat, outlon, which); -} +human_to_dec(const QString& instr, double* outlat, double* outlon, int which); QString dec_to_human(const char* format, const char* dirs, double val); diff --git a/gpx.cc b/gpx.cc index 5db2f75de..b6803bf78 100644 --- a/gpx.cc +++ b/gpx.cc @@ -487,7 +487,9 @@ xml_parse_time(const QString& dateTimeString) int off_hr = 0; int off_min = 0; int off_sign = 1; - char* timestr = xstrdup(dateTimeString); + + QByteArray dts = dateTimeString.toUtf8(); + char* timestr = dts.data(); char* offsetstr = strchr(timestr, 'Z'); if (offsetstr) { @@ -545,7 +547,6 @@ xml_parse_time(const QString& dateTimeString) } else { dt = QDateTime(); } - xfree(timestr); return dt; } diff --git a/nmea.cc b/nmea.cc index 92d284c08..dac71f88b 100644 --- a/nmea.cc +++ b/nmea.cc @@ -271,6 +271,9 @@ NmeaFormat::rd_deinit() break; } + nmea_release_wpt(curr_waypt); + curr_waypt = nullptr; + posn_fname.clear(); } diff --git a/reference/humantodec.gpx b/reference/humantodec.gpx new file mode 100644 index 000000000..37bfa1db4 --- /dev/null +++ b/reference/humantodec.gpx @@ -0,0 +1,100 @@ + + + + + + point0 + point0 + point0 + + + point1 + point1 + point1 + + + point2 + point2 + point2 + + + point3 + point3 + point3 + + + point4 + point4 + point4 + + + point5 + point5 + point5 + + + point6 + point6 + point6 + + + point7 + point7 + point7 + + + point8 + point8 + point8 + + + point9 + point9 + point9 + + + point10 + point10 + point10 + + + point11 + point11 + point11 + + + point12 + point12 + point12 + + + point13 + point13 + point13 + + + point14 + point14 + point14 + + + point15 + point15 + point15 + + + point16 + point16 + point16 + + + point17 + point17 + point17 + + + point18 + point18 + point18 + + diff --git a/reference/humantodec1.csv b/reference/humantodec1.csv new file mode 100644 index 000000000..5b12efd2e --- /dev/null +++ b/reference/humantodec1.csv @@ -0,0 +1,20 @@ +lat,lon,desc +1.234°S,5.678°W,point0 +1°14.04′S,5°40.68′W,point1 +1°14′2.4″S,5°40′40.8″W,point2 +S1.234°,W5.678°,point3 +S1°14.04′,W5°40.68′,point4 +S1°14′2.4″,W5°40′40.8″,point5 +-1.234°,-5.678°,point6 +-1°14.04′,-5°40.68′,point7 +-1°14′2.4″,-5°40′40.8″,point8 +1.234° S,5.678° W,point9 +1° 14.04′ S,5° 40.68′ W,point10 +1° 14′ 2.4″ S,5° 40′ 40.8″ W,point11 +S 1.234°,W 5.678°,point12 +S 1° 14.04′,W 5° 40.68′,point13 +S 1° 14′ 2.4″,W 5° 40′ 40.8″,point14 +-1.234°,-5.678°,point15 +-1° 14.04′,-5° 40.68′,point16 +-1° 14′ 2.4″,-5° 40′ 40.8″,point17 +-1.234,-5.678,point18 diff --git a/reference/humantodec2.csv b/reference/humantodec2.csv new file mode 100644 index 000000000..497c532c8 --- /dev/null +++ b/reference/humantodec2.csv @@ -0,0 +1,20 @@ +lat lon desc +1,234°S 5,678°W point0 +1°14,04′S 5°40,68′W point1 +1°14′2,4″S 5°40′40,8″W point2 +S1,234° W5,678° point3 +S1°14,04′ W5°40,68′ point4 +S1°14′2,4″ W5°40′40,8″ point5 +-1,234° -5,678° point6 +-1°14,04′ -5°40,68′ point7 +-1°14′2,4″ -5°40′40,8″ point8 +1,234° S 5,678° W point9 +1° 14,04′ S 5° 40,68′ W point10 +1° 14′ 2,4″ S 5° 40′ 40,8″ W point11 +S 1,234° W 5,678° point12 +S 1° 14,04′ W 5° 40,68′ point13 +S 1° 14′ 2,4″ W 5° 40′ 40,8″ point14 +-1,234° -5,678° point15 +-1° 14,04′ -5° 40,68′ point16 +-1° 14′ 2,4″ -5° 40′ 40,8″ point17 +-1,234 -5,678 point18 diff --git a/testo.d/unicsv.test b/testo.d/unicsv.test index 03383562a..115a92bea 100644 --- a/testo.d/unicsv.test +++ b/testo.d/unicsv.test @@ -41,3 +41,8 @@ compare ${REFERENCE}/libreoffice.text ${TMPDIR}/libreoffice.text gpsbabel -i unicsv -f ${REFERENCE}/libreoffice.csv -o unicsv -F ${TMPDIR}/libreoffice2.csv gpsbabel -i unicsv -f ${TMPDIR}/libreoffice2.csv -o text,degformat=ddd -F ${TMPDIR}/libreoffice2.text compare ${REFERENCE}/libreoffice.text ${TMPDIR}/libreoffice2.text + +gpsbabel -i unicsv -f ${REFERENCE}/humantodec1.csv -o gpx -F ${TMPDIR}/humantodec1.gpx +compare ${REFERENCE}/humantodec.gpx ${TMPDIR}/humantodec1.gpx +gpsbabel -i unicsv -f ${REFERENCE}/humantodec2.csv -o gpx -F ${TMPDIR}/humantodec2.gpx +compare ${REFERENCE}/humantodec.gpx ${TMPDIR}/humantodec2.gpx diff --git a/xcsv.cc b/xcsv.cc index f161c7952..99a9543c0 100644 --- a/xcsv.cc +++ b/xcsv.cc @@ -455,7 +455,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle: wpt->latitude = intdeg_to_dec((int) atof(s)); break; case XcsvStyle::XT_LAT_HUMAN_READABLE: - human_to_dec(s, &wpt->latitude, &wpt->longitude, 1); + human_to_dec(value, &wpt->latitude, &wpt->longitude, 1); break; case XcsvStyle::XT_LAT_DDMMDIR: wpt->latitude = ddmmdir_to_degrees(s); @@ -479,7 +479,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle: wpt->longitude = intdeg_to_dec((int) atof(s)); break; case XcsvStyle::XT_LON_HUMAN_READABLE: - human_to_dec(s, &wpt->latitude, &wpt->longitude, 2); + human_to_dec(value, &wpt->latitude, &wpt->longitude, 2); break; case XcsvStyle::XT_LON_DDMMDIR: wpt->longitude = ddmmdir_to_degrees(s); @@ -490,7 +490,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle: // case XcsvStyle::XT_LON_10E is handled outside the switch. /* LAT AND LON CONVERSIONS ********************************************/ case XcsvStyle::XT_LATLON_HUMAN_READABLE: - human_to_dec(s, &wpt->latitude, &wpt->longitude, 0); + human_to_dec(value, &wpt->latitude, &wpt->longitude, 0); break; /* DIRECTIONS **********************************************************/ case XcsvStyle::XT_LAT_DIR: @@ -638,7 +638,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle: break; case XcsvStyle::XT_ISO_TIME: case XcsvStyle::XT_ISO_TIME_MS: - wpt->SetCreationTime(xml_parse_time(s)); + wpt->SetCreationTime(xml_parse_time(value)); break; case XcsvStyle::XT_NET_TIME: { bool ok; -- 2.30.2